package cn.lkp.mall.ware.controller;

import java.util.Arrays;
import java.util.List;
import java.util.Map;


import cn.lkp.common.expection.BizCodeException;
import cn.lkp.common.expection.NoStockException;
import cn.lkp.mall.ware.vo.SkuHasStockVo;
import cn.lkp.mall.ware.vo.WareSkuLockVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import cn.lkp.mall.ware.entity.WareSkuEntity;
import cn.lkp.mall.ware.service.WareSkuService;
import cn.lkp.common.utils.PageUtils;
import cn.lkp.common.utils.R;



/**
 * 商品库存
 *
 * @author lkp
 * @email 271309236@qq.com
 * @date 2020-11-11 14:50:10
 */
@RestController
@RequestMapping("ware/waresku")
public class WareSkuController {
    @Autowired
    private WareSkuService wareSkuService;
    /**
     * 锁定库存
     * @param vo
     *
     * 库存解锁的场景
     *      1）、下订单成功，订单过期没有支付被系统自动取消或者被用户手动取消，都要解锁库存
     *      2）、下订单成功，库存锁定成功，接下来的业务调用失败，导致订单回滚。之前锁定的库存就要自动解锁
     *      3）、
     *
     * @return
     */
    //请求传递批量数据用@RequestBody,@RequestBody接收的参数是来自requestBody中，即请求体。
    //一般用于处理Content-Type: application/json、application/xml等类型的数据。
    // 比如传递json字符串，使用@PostMapping  GET请求中，因为没有HttpEntity，所以@RequestBody并不适用。
    @PostMapping("/lock/order")
    public R orderLockStock(@RequestBody WareSkuLockVo vo){
        try{
            Boolean lockStock = wareSkuService.orderLockStock(vo);
            return R.ok().setData(lockStock);
        }catch(NoStockException e){
            return R.error(BizCodeException.NO_STOCK_EXCEPTION.getCode(),BizCodeException.NO_STOCK_EXCEPTION.getMsg());
        }
    }

    /**
     * 查询sku是否有库存
     */
    //请求传递批量数据用@RequestBody,@RequestBody接收的参数是来自requestBody中，即请求体。
    //一般用于处理Content-Type: application/json、application/xml等类型的数据。
    // 比如传递json字符串，使用@PostMapping  GET请求中，因为没有HttpEntity，所以@RequestBody并不适用。
    @PostMapping("/hasstock")
    public R getSkuHasStock(@RequestBody List<Long> skuIds){
        //返回集合，类型是vo,里面封装skuId 和 hasStock
        List<SkuHasStockVo> vos = wareSkuService.getSkuHasStock(skuIds);
        //由于data是List类型的vo,需要从远程调用返回的R当中获取到data，然后再将data内容再转化为我们需要的类型，这样比较麻烦
        //第一种方案：最初设计R类型时就加入泛型,这里就可以直接将泛型写成返回所需要的指定类型
        //第二种方案: 将R修改为我们指定的类型，直接返回
        //第三种方案：自己封装解析结果
        //这里我们使用第一种方案
        //R<List<SkuHasStockVo>> ok = R.ok();
        //在这里打断点，测试发现ok里面没有放入data,说明这个泛型写的有问题，改为返回R类型。
        // 在R中编写方法R setData(Object data)和<T> T getData(TypeReference<T> typeReference)
        // 这样传入什么类型的类型，就返回什么样的类型。如List<SkuHasStockVo>
        //ok.setData(vos);
        R ok = R.ok();
        ok.setData(vos);
        return ok;
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    //@RequiresPermissions("ware:waresku:list")
    public R list(@RequestParam Map<String, Object> params){
        //PageUtils page = wareSkuService.queryPage(params);
        PageUtils page = wareSkuService.queryPageByCondition(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    //@RequiresPermissions("ware:waresku:info")
    public R info(@PathVariable("id") Long id){
        WareSkuEntity wareSku = wareSkuService.getById(id);

        return R.ok().put("wareSku", wareSku);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("ware:waresku:save")
    public R save(@RequestBody WareSkuEntity wareSku){
        wareSkuService.save(wareSku);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    //@RequiresPermissions("ware:waresku:update")
    public R update(@RequestBody WareSkuEntity wareSku){
        wareSkuService.updateById(wareSku);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    //@RequiresPermissions("ware:waresku:delete")
    public R delete(@RequestBody Long[] ids){
        wareSkuService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}
